package dao

import (
	"time"

	"gitee.com/huangxinbo/xcas/internal/app/base"
	"gitee.com/huangxinbo/xcas/internal/model/db_model"
	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
	"go.uber.org/zap"
	"gorm.io/gorm"
)

type CasTicketDAO struct {
	base *base.Base
}

func NewCasTicketDAO(base *base.Base) *CasTicketDAO {
	return &CasTicketDAO{
		base: base,
	}
}

// CreateTicket 创建CAS票证
func (d *CasTicketDAO) CreateTicket(ctx *gin.Context, ticket *db_model.CasTicket) error {
	result := d.base.Db.WithContext(ctx).Create(ticket)
	if result.Error != nil {
		d.base.Logger.Error("Failed to create CAS ticket", zap.Error(result.Error))
		return result.Error
	}
	return nil
}

// GetTicketByID 根据票证ID获取票证
func (d *CasTicketDAO) GetTicketByID(ctx *gin.Context, ticketID string) (*db_model.CasTicket, error) {
	var ticket db_model.CasTicket
	result := d.base.Db.WithContext(ctx).Where("id = ?", ticketID).First(&ticket)
	if result.Error != nil {
		if result.Error == gorm.ErrRecordNotFound {
			return nil, nil
		}
		d.base.Logger.Error("Failed to get CAS ticket by ID", zap.Error(result.Error))
		return nil, result.Error
	}
	return &ticket, nil
}

// DeleteTicket 删除票证
func (d *CasTicketDAO) DeleteTicket(ctx *gin.Context, ticketID string) error {
	result := d.base.Db.WithContext(ctx).Where("id = ?", ticketID).Delete(&db_model.CasTicket{})
	if result.Error != nil {
		d.base.Logger.Error("Failed to delete CAS ticket", zap.Error(result.Error))
		return result.Error
	}
	return nil
}

// GetTicketsByPrincipalID 根据用户ID获取所有票证
func (d *CasTicketDAO) GetTicketsByPrincipalID(ctx *gin.Context, principalID uuid.UUID) ([]*db_model.CasTicket, error) {
	var tickets []*db_model.CasTicket
	result := d.base.Db.WithContext(ctx).Where("principal_id = ?", principalID).Find(&tickets)
	if result.Error != nil {
		d.base.Logger.Error("Failed to get CAS tickets by principal ID", zap.Error(result.Error))
		return nil, result.Error
	}
	return tickets, nil
}

// GetSTsByTGT 根据TGT获取所有ST
func (d *CasTicketDAO) GetSTsByTGT(ctx *gin.Context, tgtID string) ([]*db_model.CasTicket, error) {
	var sts []*db_model.CasTicket
	result := d.base.Db.WithContext(ctx).Where("parent_id = ? AND type = ?", tgtID, db_model.TicketTypeST).Find(&sts)
	if result.Error != nil {
		d.base.Logger.Error("Failed to get STs by TGT", zap.Error(result.Error))
		return nil, result.Error
	}
	return sts, nil
}

// CleanExpiredTickets 清理过期票证
func (d *CasTicketDAO) CleanExpiredTickets(ctx *gin.Context) error {
	result := d.base.Db.WithContext(ctx).Where("expired_at < ?", time.Now()).Delete(&db_model.CasTicket{})
	if result.Error != nil {
		d.base.Logger.Error("Failed to clean expired CAS tickets", zap.Error(result.Error))
		return result.Error
	}
	return nil
}
